#include "LocalScene.h"
#include "Utils/LogUtil.h"
#include "LocalEntity.h"
#include "Utils/StringUtil.h"
#include "Game/Component/Model.h"
#include "Render/RenderState.h"
#include "Render/Imgui/imgui.h"
#include "Math/Random.h"


void LocalScene::OnInit()
{
	mCoordinateProcess = GetProcess<CoordinateProcess>("CoordinateProcess");
	mPbrProcess = GetProcess<PbrProcess>("PbrProcess");
	mHdrProcess = GetProcess<HdrProcess>("HdrProcess");

	mColorProcess = 0;
	mCubemapProcess = 0;

	GeometryGenerator geometryGenerator;
	GeometryGenerator::MeshData sphereData = geometryGenerator.CreateGeosphere(0.2f, 5);


	mLightActives.resize(4, 1);
	mLightEntitys.resize(4, nullptr);
	for (uint32 i = 0; i < 4; ++i)
	{
		LocalEntity* lightEntity = CreateEntity<LocalEntity>();
		lightEntity->AddComponent<Model>(sphereData);
		glm::vec3 color(1.f);
		glm::vec3 pos(6.f, 6.f, 6.f);
		switch (i)
		{
		case 1:
			color = glm::vec3(1.f, 0.f, 0.f);
			pos = glm::vec3(6.f, -6.f, 6.f);
			break;
		case 2:
			color = glm::vec3(0.f, 1.f, 0.f);
			pos = glm::vec3(-6.f, 6.f, 6.f);
			break;
		case 3:
			color = glm::vec3(0.f, 0.f, 1.f);
			pos = glm::vec3(-6.f, -6.f, 6.f);
			break;
		}
		lightEntity->AddComponent<Light>(color);
		lightEntity->GetTransform().SetLocalPosition(pos);
		lightEntity->GetTransform().UpdateMatrices();
		mLightEntitys[i] = lightEntity;
	}


	GeometryGenerator::MeshData bigSphereData = geometryGenerator.CreateGeosphere(0.6f, 30);
	// GeometryGenerator::MeshData bigSphereData = geometryGenerator.CreateSphere(0.6f, 30, 30);

	LocalEntity* sphere = CreateEntity<LocalEntity>("Sphere");
	sphere->AddComponent<Model>(bigSphereData);
	sphere->AddComponent<PbrType>();

	LocalEntity* torusknot = CreateEntity<LocalEntity>("Torusknot");
	torusknot->AddComponent<Model>("Torusknot.obj");
	torusknot->AddComponent<PbrType>();
	torusknot->GetTransform().SetLocalScale(glm::vec3(0.8f));
	torusknot->GetTransform().UpdateMatrices();

	LocalEntity* venus = CreateEntity<LocalEntity>("Venus");
	venus->AddComponent<Model>("Venus.obj");
	venus->AddComponent<PbrType>();
	venus->GetTransform().SetLocalScale(glm::vec3(0.2f));
	venus->GetTransform().UpdateMatrices();

	LocalEntity* teapot = CreateEntity<LocalEntity>("Teapot");
	teapot->AddComponent<Model>("Teapot.obj");
	teapot->AddComponent<PbrType>();
	teapot->GetTransform().SetLocalScale(glm::vec3(0.2f));
	teapot->GetTransform().UpdateMatrices();
}

void LocalScene::OnExit()
{

}

void LocalScene::OnTick(float deltaTime)
{

}

void LocalScene::OnImgui()
{
	GameScene::OnImgui();


	ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);

	ImGui::Begin("PbrOption");

	for (uint32 i = 0; i < 4; ++i)
	{
		bool* isActive = ((bool*)mLightActives.data()) + i;
		const std::string lightName = STRFORMAT("Light %d", i);
		if (ImGui::Checkbox(lightName.c_str(), isActive))
		{
			mLightEntitys[i]->GetComponent<Light>().mActive = (bool)*isActive;
			// LOGI(L"Light Active %d --> %d", i, (uint8)*isActive);
		}
	}

	ImGui::InputFloat("Exposure", &mHdrProcess->mExposure, 0.025f, 0.25f);
	ImGui::InputFloat("Gamma", &mHdrProcess->mGamma, 0.025f, 0.25f);

	ImGui::Combo("ModelSelect", &mPbrProcess->mObjectIndex, &mPbrProcess->mObjectNames[0], 4, 4);

	ImGui::Combo("MaterialSelect", &mPbrProcess->mMaterialIndex, &mPbrProcess->mMaterialNames[0], 11, 11);

	ImGui::RadioButton("Pbr", &mPbrProcess->mWatchMode, 0);
	ImGui::RadioButton("Roughness", &mPbrProcess->mWatchMode, 1);
	ImGui::RadioButton("Metallic", &mPbrProcess->mWatchMode, 2);
	ImGui::RadioButton("Fresnel 0", &mPbrProcess->mWatchMode, 3);
	ImGui::RadioButton("Fresnel", &mPbrProcess->mWatchMode, 4);
	ImGui::RadioButton("Albedo", &mPbrProcess->mWatchMode, 5);
	ImGui::RadioButton("No Gamma", &mPbrProcess->mWatchMode, 6);
	ImGui::RadioButton("Lo", &mPbrProcess->mWatchMode, 7);
	ImGui::RadioButton("Lo and Gamma", &mPbrProcess->mWatchMode, 8);
	ImGui::RadioButton("Fresnel Roughness", &mPbrProcess->mWatchMode, 9);

	ImGui::Text("SelectProcess");
	ImGui::RadioButton("PbrIBL", &mColorProcess, 0);
	ImGui::RadioButton("Brbflut", &mColorProcess, 1);
	ImGui::RadioButton("IrradianceHdr", &mColorProcess, 2);
	ImGui::RadioButton("IrradianceCubemap", &mColorProcess, 3);


	switch (mColorProcess)
	{
	case 0:
		mCoordinateProcess->UpdateColorRenderTarget("LocalProcess", "ColorRenderTarget");
		break;
	case 1:
		mCoordinateProcess->UpdateColorRenderTarget("BrbflutProcess", "ColorRenderTarget");
		break;
	case 2:
		mCoordinateProcess->UpdateColorRenderTarget("IrradianceHdrProcess", "ColorRenderTarget");
		break;
	case 3:
		mCoordinateProcess->UpdateColorRenderTarget("IrradianceCubemapProcess", "ColorRenderTarget");
		break;
	}


	ImGui::Text("SelectCubemap");
	ImGui::RadioButton("Hdr Cubemap", &mCubemapProcess, 0);
	ImGui::RadioButton("Irradiance Cubemap", &mCubemapProcess, 1);
	ImGui::RadioButton("Prefilterenvmap Cubemap", &mCubemapProcess, 2);

	switch (mCubemapProcess)
	{
	case 0:
		mHdrProcess->UpdateCubemap("IrradianceCubemapProcess");
		break;
	case 1:
		mHdrProcess->UpdateCubemap("IrradianceProcess");
		break;
	case 2:
		mHdrProcess->UpdateCubemap("PrefilterenvmapProcess");
		break;
	}


	ImGui::End();

}
